package shanghaielectric_lib.DB;

import android.util.Log;

import org.litepal.crud.DataSupport;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import shanghaielectric_lib.DB.Model.DB_Device;
import shanghaielectric_lib.DB.Model.DB_DeviceType;
import shanghaielectric_lib.DB.Model.DB_Device_moubusRTU;
import shanghaielectric_lib.DB.Model.DB_Device_moubusTCP;
import shanghaielectric_lib.DB.Model.DB_Point;
import shanghaielectric_lib.DB.Model.DB_Point_EnumData;
import shanghaielectric_lib.DB.Model.DB_Point_modbus;
import shanghaielectric_lib.DeviceConfigModel.Device.Device;
import shanghaielectric_lib.DeviceConfigModel.Device.DeviceModbusRTU;
import shanghaielectric_lib.DeviceConfigModel.Device.DeviceModbusTCP;
import shanghaielectric_lib.DeviceConfigModel.Device.DeviceType;
import shanghaielectric_lib.DeviceConfigModel.Device.ModbusRTUParamDevice;
import shanghaielectric_lib.DeviceConfigModel.Device.ModbusTCPParamDevice;
import shanghaielectric_lib.DeviceConfigModel.Point.EnumPoint;
import shanghaielectric_lib.DeviceConfigModel.Point.Point;
import shanghaielectric_lib.DeviceConfigModel.Point.PointEnumData;
import shanghaielectric_lib.DeviceConfigModel.Point.ProtocolParam_Point_104;
import shanghaielectric_lib.DeviceConfigModel.Point.ProtocolParam_Point_Modbus;
import shanghaielectric_lib.EnumDataHelper;
import shanghaielectric_lib.Utils.LogUtil;


/**
 * Created by cuihanbing on 2017/10/20.
 */

public class DBHelper_config {

    private List<Device> deviceList;
    private List<DeviceType> deviceTypeList;
    private List<DeviceModbusRTU> deviceModbusRTUlist;
    private List<DeviceModbusTCP> deviceModbusTCPlist;
    private List<ProtocolParam_Point_Modbus> modbuslistParampoint;
    private List<PointEnumData> pointEnumDataMap_all;
    private static DBHelper_config dbHelper_config;

    private List<DB_Device> db_deviceList;
    private List<DB_DeviceType> db_deviceTypeList;
    private List<DB_Device_moubusRTU> db_Device_moubusRTUs;
    private List<DB_Device_moubusTCP> db_device_moubusTCPs;
    private List<DB_Point_EnumData> db_PointEnumData;
    private List<DB_Point_modbus> db_point_modbus;

    private DBHelper_config() {

        deviceList = new ArrayList<>();
        db_deviceList = get_DB_DeviceList();
        db_deviceTypeList = get_DB_DeviceTypeList();
        db_Device_moubusRTUs = get_DB_Device_modbusRTU();
        db_device_moubusTCPs = get_DB_Device_modbusTCP();
        db_PointEnumData = get_DB_PointEnumData();
        db_point_modbus = get_DB_point_modbus();

        initDeviceType();
        initDevice();
        initPointEnumData();
        LogUtil.e("", "");
//        initPoint();
//        initPointModbus();
//        initDeviceModbusRTU();
//        initDeviceModbusTCP();
    }

    public static DBHelper_config getDBHelper_config() {

        if (dbHelper_config == null) {
            dbHelper_config = new DBHelper_config();
            return dbHelper_config;
        } else {
            return dbHelper_config;
        }
    }

    public Map<Integer, Device> getDevices() {
        Map<Integer, Device> deviceMap = new LinkedHashMap<>();
        for (int i = 0; i < deviceList.size(); i++) {
            deviceMap.put(deviceList.get(i).deviceID_d, deviceList.get(i));
        }
        return deviceMap;
    }

    public List<Device> getDeviceList() {
        return deviceList;
    }

    private void initDeviceType() {
        deviceTypeList = new ArrayList<>();
        for (int i = 0; i < db_deviceTypeList.size(); i++) {
            deviceTypeList.add(new DeviceType());
            deviceTypeList.get(i).name_dt = db_deviceTypeList.get(i).name_dt;
            deviceTypeList.get(i).protocolType_dt = db_deviceTypeList.get(i).protocol_Type_dt;
            deviceTypeList.get(i).deviceTypeId_dt = db_deviceTypeList.get(i).device_type_id_dt;
            deviceTypeList.get(i).description_dt = db_deviceTypeList.get(i).description_dt;
        }
    }

    private void initDevice() {

//        List<DB_Point_modbus> db_point_modbusList = get_DB_point_modbus();

        for (int i = 0; i < db_deviceList.size(); i++) {
            //搜先判断设备的协议类型---点赋值
            if (EnumDataHelper.PROTOCOL_TYPE.RTU.getName().equals(db_deviceList.get(i).protocol_type)) {//某台设备是RTU协议类型
                DeviceModbusRTU deviceRTU = new DeviceModbusRTU();
//初始化deviceRTU
                //mpointList类型点(包括了数据类型的转换)
                List<Point> mpointList = getPointByDeviceID(i + 1);//mpointList取得设备类型为i的点的集合；//得到的ID 用于查找pointmodbus表
                ModbusRTUParamDevice modbusRTUParamDevice = new ModbusRTUParamDevice();
                modbusRTUParamDevice.slaveID = db_Device_moubusRTUs.get(i).slave_ID;
                modbusRTUParamDevice.stopBits = db_Device_moubusRTUs.get(i).stopBits;
                modbusRTUParamDevice.baudRate = db_Device_moubusRTUs.get(i).dataBits;
                modbusRTUParamDevice.comID = db_Device_moubusRTUs.get(i).com_ID;
                modbusRTUParamDevice.parityBits = db_Device_moubusRTUs.get(i).parityBits;
                modbusRTUParamDevice.deviceID = db_Device_moubusRTUs.get(i).device_ID;
                modbusRTUParamDevice.dataBits = db_Device_moubusRTUs.get(i).dataBits;
                deviceRTU.modbusRTUParam = modbusRTUParamDevice;

                deviceRTU.description = db_deviceList.get(i).description;
                deviceRTU.protocolType = EnumDataHelper.PROTOCOL_TYPE.valueOf(db_deviceList.get(i).protocol_type);
                deviceRTU.deviceTypeID = db_deviceList.get(i).device_type_id;
                deviceRTU.name = db_deviceList.get(i).name;
                DB_DeviceType deviceType = getDeviceTypeByDeviceID(i);
                deviceRTU.description_dt = deviceType.description_dt;
                deviceRTU.name_dt = deviceType.name_dt;
                deviceRTU.protocolType_dt = deviceType.protocol_Type_dt;
                deviceRTU.pointList = mpointList;
                deviceRTU.deviceTypeId_dt = deviceType.device_type_id_dt;
                deviceRTU.deviceID_d = db_deviceList.get(i).device_id;
                deviceList.add(deviceRTU);
            } else if (EnumDataHelper.PROTOCOL_TYPE.TCP.getName().equals(db_deviceList.get(i).protocol_type)) {
                DeviceModbusTCP deviceModbusTCP = new DeviceModbusTCP();

                List<Point> mpointList = getPointByDeviceID(i + 1);//mpointList取得设备类型为i的点的集合；//得到的ID 用于查找pointmodbus表
                ModbusTCPParamDevice modbusTCPParamDevice = new ModbusTCPParamDevice();
                modbusTCPParamDevice.deviceID = db_device_moubusTCPs.get(i).deviceID;
                modbusTCPParamDevice.slaveID = db_device_moubusTCPs.get(i).slaveID;
                modbusTCPParamDevice.ipAddress = db_device_moubusTCPs.get(i).ipAddress;
                modbusTCPParamDevice.port = db_device_moubusTCPs.get(i).port;

                deviceModbusTCP.modbusTCPParam = modbusTCPParamDevice;
                deviceModbusTCP.pointList = mpointList;
                deviceModbusTCP.deviceTypeID = db_deviceList.get(i).device_type_id;
                deviceModbusTCP.description = db_deviceList.get(i).description;
                deviceModbusTCP.name = db_deviceList.get(i).name;
                DB_DeviceType deviceType = getDeviceTypeByDeviceID(i);
                deviceModbusTCP.description_dt = deviceType.description_dt;
                deviceModbusTCP.name_dt = deviceType.name_dt;
                deviceModbusTCP.name = db_deviceList.get(i).name;
                deviceModbusTCP.protocolType = EnumDataHelper.PROTOCOL_TYPE.valueOf(db_deviceList.get(i).protocol_type);
                deviceModbusTCP.protocolType_dt = deviceType.protocol_Type_dt;
                deviceModbusTCP.deviceTypeId_dt = deviceType.device_type_id_dt;
                deviceModbusTCP.deviceID_d = db_deviceList.get(i).device_id;
                deviceList.add(deviceModbusTCP);
            }
        }
    }


    private void initPointEnumData() {
        pointEnumDataMap_all = new ArrayList<>();

        for (int i = 0; i < db_PointEnumData.size(); i++) {
            PointEnumData pointEnumData = new PointEnumData();
            pointEnumData.pointID = db_PointEnumData.get(i).pointID;
            pointEnumData.enumKey = db_PointEnumData.get(i).enumKey;
            pointEnumData.enumValue = db_PointEnumData.get(i).enumValue;
            pointEnumDataMap_all.add(pointEnumData);

        }
    }

    public List<PointEnumData> getPointEnumDataList() {
        if (pointEnumDataMap_all == null) {
            initPointEnumData();
        }
        return pointEnumDataMap_all;
    }

    //  DB_DeviceType
//  DB_Device
    private List<DB_DeviceType> get_DB_DeviceTypeList() {
        List<DB_DeviceType> list = new ArrayList<>();
        list = DataSupport.findAll(DB_DeviceType.class);
        return list;
    }

    //  DB_Device
    private List<DB_Device> get_DB_DeviceList() {
        List<DB_Device> list = new ArrayList<>();
        list = DataSupport.findAll(DB_Device.class);
//        LogUtil.e("6666", "" + list.size());
        return list;
    }

    //  DB_Device_moubusRTU
    private List<DB_Device_moubusRTU> get_DB_Device_modbusRTU() {
        List<DB_Device_moubusRTU> list = new ArrayList<>();
        list = DataSupport.findAll(DB_Device_moubusRTU.class);
        return list;
    }

    //  DB_Device_moubusTCP
    private List<DB_Device_moubusTCP> get_DB_Device_modbusTCP() {
        List<DB_Device_moubusTCP> list = new ArrayList<>();
        list = DataSupport.findAll(DB_Device_moubusTCP.class);
        return list;
    }

    //  DB_Point
    public List<DB_Point> get_DB_point() {
        List<DB_Point> list = new ArrayList<>();
        list = DataSupport.findAll(DB_Point.class);
        return list;
    }

    //  DB_Point_modbus
    private List<DB_Point_modbus> get_DB_point_modbus() {
        List<DB_Point_modbus> list = new ArrayList<>();
        list = DataSupport.findAll(DB_Point_modbus.class);
        return list;
    }

    //  DB_Point_EnumData
    private List<DB_Point_EnumData> get_DB_PointEnumData() {
        List<DB_Point_EnumData> list = new ArrayList<>();
        list = DataSupport.findAll(DB_Point_EnumData.class);
        return list;
    }

    private DB_DeviceType getDeviceTypeByDeviceID(int deviceID) {

        int deviceTypeID = 1;// save the device's deviceTypeID
        for (DB_Device db_device : db_deviceList) {
            deviceTypeID = (db_device.device_id == deviceID) ? db_device.device_type_id : deviceTypeID;
        }
        DB_DeviceType db_deviceType = db_deviceTypeList.get(0);
        for (DB_DeviceType type : db_deviceTypeList
                ) {
            db_deviceType = (type.device_type_id_dt == deviceTypeID) ? type : db_deviceType;
        }
        return db_deviceType;
    }

    //该点集已经包含了必要的数据
    private List<Point> getPointByDeviceID(int deviceID) {
        List<Point> points = new ArrayList<>();
        int deviceTypeID = 0;// save the device's deviceTypeID
        for (DB_Device db_device : db_deviceList) {
            if (db_device.device_id == deviceID) {
                deviceTypeID = db_device.device_type_id;
            }
        }

        List<DB_Point> db_points;
        db_points = DataSupport.where("devicetypeid = ?", deviceTypeID + "").find(DB_Point.class);
        for (int i = 0; i < db_points.size(); i++) {
            if (EnumDataHelper.POINT_DATETYPE.ENUM.getName().equals(db_points.get(i).type)) {
                //枚举点
                EnumPoint enumpoint = new EnumPoint();
                List<PointEnumData> mpointEnumDataList = new ArrayList<>();
                mpointEnumDataList = getPointEnumDataListbyPointID(i);//point点里第几个点是enum类型的，因而查找使用的索引就是i
                enumpoint.pointEnumDataList = mpointEnumDataList;
                points.add(enumpoint);
            } else {
                points.add(new Point());
            }
            points.get(i).pointID = db_points.get(i).pointID;
            points.get(i).pointDatetype = EnumDataHelper.POINT_DATETYPE.valueOf(db_points.get(i).type);
            points.get(i).deviceID = db_points.get(i).deviceTypeID;
            points.get(i).name = db_points.get(i).name;
            points.get(i).scale = db_points.get(i).scale;
            points.get(i).idDisplay = db_points.get(i).isDisplay;
            points.get(i).initValue = db_points.get(i).initValue;
            points.get(i).maxValue = db_points.get(i).maxValue;
            points.get(i).minValue = db_points.get(i).minValue;
            points.get(i).isInternal = db_points.get(i).isInternal;
            points.get(i).precision = db_points.get(i).precision;
            points.get(i).unit = db_points.get(i).unit;
            points.get(i).protocolType = db_points.get(i).protocolType;
            points.get(i).idDisplay = db_points.get(i).isDisplay;
            points.get(i).isRead = db_points.get(i).isread;
            if (EnumDataHelper.PROTOCOL_TYPE.RTU.getName().equals(db_points.get(i).protocolType) | EnumDataHelper.PROTOCOL_TYPE.TCP.getName().equals(db_points.get(i).protocolType)) {
                ProtocolParam_Point_Modbus protocolParam_Point_Modbus = new ProtocolParam_Point_Modbus();
                protocolParam_Point_Modbus.address = db_point_modbus.get(points.get(i).pointID - 1).address;
                protocolParam_Point_Modbus.pointID = db_point_modbus.get(points.get(i).pointID - 1).pointID;
                protocolParam_Point_Modbus.slaveID = db_point_modbus.get(points.get(i).pointID - 1).slaveID;
                protocolParam_Point_Modbus.modbusDataType = EnumDataHelper.MODBUS_DATA_TYPE.valueOf(db_point_modbus.get(points.get(i).pointID - 1).type_bit);
                points.get(i).protocolParam_point = protocolParam_Point_Modbus;
            } else if (EnumDataHelper.PROTOCOL_TYPE._104.getName().equals(db_points.get(i).protocolType)) {
                ProtocolParam_Point_104 protocolParam_Point_104 = new ProtocolParam_Point_104();
                protocolParam_Point_104.address = db_point_modbus.get(points.get(i).pointID - 1).address;
                protocolParam_Point_104.pointID = db_point_modbus.get(points.get(i).pointID - 1).pointID;
                points.get(i).protocolParam_point = protocolParam_Point_104;
            }
        }
        return points;
    }

    private List<PointEnumData> getPointEnumDataListbyPointID(int pointID_index) {
        List<PointEnumData> pointEnums = new ArrayList<>();
        List<DB_Point_EnumData> db_pointEnumDatalist = DataSupport.where("pointid=?", String.valueOf(pointID_index)).find(DB_Point_EnumData.class);
        for (int i = 0; i < db_pointEnumDatalist.size(); i++) {
            PointEnumData pointEnum = new PointEnumData();
            pointEnum.pointID = db_pointEnumDatalist.get(i).pointID;
            pointEnum.enumValue = db_pointEnumDatalist.get(i).enumValue;
            pointEnum.enumKey = db_pointEnumDatalist.get(i).enumKey;
            pointEnums.add(pointEnum);
        }
        LogUtil.e("", "" + pointEnums);
        return pointEnums;
    }
    public List<PointEnumData> getPointEnumDataListbyPointID_(int pointID_index) {
        List<PointEnumData> list = getPointEnumDataList();
        List<PointEnumData> pointEnumDataList=new ArrayList<>();

            for (int i = 0; i < list.size(); i++) {
                if (list.get(i).pointID==pointID_index){
                    pointEnumDataList.add(list.get(i));
                }
            }
        return pointEnumDataList;
    }
}
